home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Mail / pine3.92 / pine / osdep / sendmail < prev    next >
Text File  |  1996-03-14  |  7KB  |  254 lines

  1. /*----------------------------------------------------------------------
  2.     Routines used to hand off messages to local agents for sending/posting
  3.  
  4.  The two exported routines are:
  5.  
  6.     1) smtp_command()  -- used to get local transport agent to invoke
  7.     2) post_handoff()  -- used to pass messages to local posting agent
  8.  
  9.  ----*/
  10.  
  11.  
  12.  
  13. /*
  14.  * Protos for "sendmail" internal functions
  15.  */
  16. static char *mta_parse_post PROTO((METAENV *, BODY *, char *, char *));
  17. static long  pine_pipe_soutr_nl PROTO((void *, char *));
  18.  
  19.  
  20.  
  21. /* ----------------------------------------------------------------------
  22.    Figure out command to start local SMTP agent
  23.  
  24.   Args: errbuf   -- buffer for reporting errors (assumed non-NULL)
  25.  
  26.   Returns an alloc'd copy of the local SMTP agent invocation or NULL
  27.  
  28.   ----*/
  29. char *
  30. smtp_command(errbuf)
  31.     char *errbuf;
  32. {
  33. #if    defined(SENDMAIL) && defined(SENDMAILFLAGS)
  34.     char tmp[256];
  35.  
  36.     sprintf(tmp, "%s %s", SENDMAIL, SENDMAILFLAGS);
  37.     return(cpystr(tmp));
  38. #else
  39.     strcpy(errbuf, "No default posting command.");
  40.     return(NULL);
  41. #endif
  42. }
  43.  
  44.  
  45.  
  46. /*----------------------------------------------------------------------
  47.    Hand off given message to local posting agent
  48.  
  49.   Args: envelope -- The envelope for the BCC and debugging
  50.         header   -- The text of the message header
  51.         errbuf   -- buffer for reporting errors (assumed non-NULL)
  52.      
  53.    ----*/
  54. int
  55. mta_handoff(header, body, errbuf)
  56.     METAENV    *header;
  57.     BODY       *body;
  58.     char       *errbuf;
  59. {
  60.     char cmd_buf[256], *cmd = NULL;
  61.  
  62.     /*
  63.      * A bit of complicated policy implemented here.
  64.      * There are two posting variables sendmail-path and smtp-server.
  65.      * Precedence is in that order.
  66.      * They can be set one of 4 ways: fixed, command-line, user, or globally.
  67.      * Precedence is in that order.
  68.      * Said differently, the order goes something like what's below.
  69.      * 
  70.      * NOTE: the fixed/command-line/user precendence handling is also
  71.      *         indicated by what's pointed to by ps_global->VAR_*, but since
  72.      *         that also includes the global defaults, it's not sufficient.
  73.      */
  74.  
  75.     if(ps_global->FIX_SENDMAIL_PATH
  76.        && ps_global->FIX_SENDMAIL_PATH[0]){
  77.     cmd = ps_global->FIX_SENDMAIL_PATH;
  78.     }
  79.     else if(!(ps_global->FIX_SMTP_SERVER
  80.           && ps_global->FIX_SMTP_SERVER[0])){
  81.     if(ps_global->COM_SENDMAIL_PATH
  82.        && ps_global->COM_SENDMAIL_PATH[0]){
  83.         cmd = ps_global->COM_SENDMAIL_PATH;
  84.     }
  85.     else if(!(ps_global->COM_SMTP_SERVER
  86.           && ps_global->COM_SMTP_SERVER[0])){
  87.         if(ps_global->USR_SENDMAIL_PATH
  88.            && ps_global->USR_SENDMAIL_PATH[0]){
  89.         cmd = ps_global->USR_SENDMAIL_PATH;
  90.         }
  91.         else if(!(ps_global->USR_SMTP_SERVER
  92.               && ps_global->USR_SMTP_SERVER[0])){
  93.         if(ps_global->GLO_SENDMAIL_PATH
  94.            && ps_global->GLO_SENDMAIL_PATH[0]){
  95.             cmd = ps_global->GLO_SENDMAIL_PATH;
  96.         }
  97. #ifdef    DF_SENDMAIL_PATH
  98.         /*
  99.          * This defines the default method of posting.  So,
  100.          * unless we're told otherwise use it...
  101.          */
  102.         else if(!(ps_global->GLO_SMTP_SERVER
  103.               && ps_global->GLO_SMTP_SERVER[0])){
  104.             strcpy(cmd = cmd_buf, DF_SENDMAIL_PATH);
  105.         }
  106. #endif
  107.         }
  108.     }
  109.     }
  110.  
  111.     *errbuf = '\0';
  112.     if(cmd){
  113.     dprint(4, (debugfile, "call_mailer via cmd: %s\n", cmd));
  114.  
  115.     (void) mta_parse_post(header, body, cmd, errbuf);
  116.     return(1);
  117.     }
  118.     else
  119.       return(0);
  120. }
  121.  
  122.  
  123.  
  124. /*----------------------------------------------------------------------
  125.    Hand off given message to local posting agent
  126.  
  127.   Args: envelope -- The envelope for the BCC and debugging
  128.         header   -- The text of the message header
  129.         errbuf   -- buffer for reporting errors (assumed non-NULL)
  130.      
  131.   Fork off mailer process and pipe the message into it
  132.   Called to post news via Inews when NNTP is unavailable
  133.   
  134.    ----*/
  135. char *
  136. post_handoff(header, body, errbuf)
  137.     METAENV    *header;
  138.     BODY       *body;
  139.     char       *errbuf;
  140. {
  141.     char *err = NULL;
  142. #ifdef    SENDNEWS
  143.     char *s;
  144.  
  145.     if(s = strstr(header->env->date," (")) /* fix the date format for news */
  146.       *s = '\0';
  147.  
  148.     if(err = mta_parse_post(header, body, SENDNEWS, errbuf))
  149.       sprintf(err = errbuf, "News not posted: \"%s\": %s", SENDNEWS, err);
  150.  
  151.     if(s)
  152.       *s = ' ';                /* restore the date */
  153.  
  154. #else /* !SENDNEWS */  /* this is the default case */
  155.     sprintf(err = errbuf, "Can't post, NNTP-server must be defined!");
  156. #endif /* !SENDNEWS */
  157.     return(err);
  158. }
  159.  
  160.  
  161.  
  162. /*----------------------------------------------------------------------
  163.    Hand off message to local MTA; it parses recipients from 822 header
  164.  
  165.   Args: header -- struct containing header data
  166.         body  -- struct containing message body data
  167.     cmd -- command to use for handoff (%s says where file should go)
  168.     errs -- pointer to buf to hold errors
  169.  
  170.    ----*/
  171. static char *
  172. mta_parse_post(header, body, cmd, errs)
  173.     METAENV *header;
  174.     BODY    *body;
  175.     char    *cmd;
  176.     char    *errs;
  177. {
  178.     char c, *p, *result = NULL;
  179.     int  rv;
  180.     PIPE_S *pipe;
  181.  
  182.     dprint(1, (debugfile, "=== mta_parse_post(%s) ===\n", cmd));
  183.  
  184.     /* tie off cmd */
  185.     for(p = cmd; (c = *p) && !isspace(*p); p++)
  186.       ;
  187.  
  188.     *p = *errs = '\0';
  189.     rv = can_access(cmd, EXECUTE_ACCESS);
  190.     *p = c;
  191.     if(!rv){
  192.     if(pipe = open_system_pipe(cmd, &result, NULL,
  193.             PIPE_STDERR | PIPE_WRITE | PIPE_PROT | PIPE_NOSHELL)){
  194.         if(!pine_rfc822_output(header, body, pine_pipe_soutr_nl,
  195.                    (TCPSTREAM *) pipe))
  196.           strcpy(errs, "Error posting.");
  197.  
  198.         if(close_system_pipe(&pipe) && !*errs){
  199.         sprintf(errs, "Posting program %s returned error", cmd);
  200.         if(result)
  201.           display_output_file(result, "POSTING ERRORS", errs);
  202.         }
  203.     }
  204.     else
  205.       sprintf(errs, "Error running cmd: %s", cmd);
  206.  
  207.     if(result){
  208.         unlink(result);
  209.         fs_give((void **)&result);
  210.     }
  211.     }
  212.     else
  213.       sprintf(errs, "Error with \"%s\" : %s", cmd,
  214.           (errno > 0) ? error_description(errno) : "not executable");
  215.  
  216.     return(*errs ? errs : NULL);
  217. }
  218.  
  219.  
  220. /* 
  221.  * pine_pipe_soutr - Replacement for tcp_soutr that writes one of our
  222.  *             pipes rather than a tcp stream
  223.  */
  224. static long
  225. pine_pipe_soutr_nl (stream,s)
  226.      void *stream;
  227.      char *s;
  228. {
  229.     long    rv = T;
  230.     char   *p;
  231.     size_t  n;
  232.  
  233.     while(*s && rv){
  234.     /* map CR LF ? */
  235.     if(n = (p = strstr(s, "\015\012")) ? p - s : strlen(s))
  236.       do
  237.         rv = fwrite(s, n, (size_t) 1, ((PIPE_S *)stream)->ofilep);
  238.       while(!rv && ferror(((PIPE_S *)stream)->ofilep) && errno == EINTR);
  239.  
  240.     if(p && rv){
  241.         s = p + 2;
  242.         do                    /* write UNIX EOL */
  243.           rv = fwrite("\n", (size_t)1, (size_t)1,
  244.               ((PIPE_S *)stream)->ofilep);
  245.         while(!rv && ferror(((PIPE_S *)stream)->ofilep)
  246.           && errno == EINTR);
  247.     }
  248.     else
  249.       break;
  250.     }
  251.  
  252.     return(rv);
  253. }
  254.